/*
 * Copyright (C) 2012 CyberAgent
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.android.gpuimage;

import android.opengl.GLES20;

public class GPUImageTextureFilter extends GPUImageTwoInputFilter {

    public static final String LOOKUP_FRAGMENT_SHADER = "varying highp vec2 textureCoordinate;\n" +
            "varying highp vec2 textureCoordinate2;\n" +
            "uniform sampler2D inputImageTexture;\n" +
            "uniform sampler2D inputImageTexture2;\n" +
            "uniform mediump float texturePercent;\n" +
            "uniform mediump float hueAdjust;\n" +
            "const highp vec4 kRGBToYPrime = vec4 (0.299, 0.587, 0.114, 0.0);\n" +
            "const highp vec4 kRGBToI = vec4 (0.595716, -0.274453, -0.321263, 0.0);\n" +
            "const highp vec4 kRGBToQ = vec4 (0.211456, -0.522591, 0.31135, 0.0);\n" +
            "const highp vec4 kYIQToR = vec4 (1.0, 0.9563, 0.6210, 0.0);\n" +
            "const highp vec4 kYIQToG = vec4 (1.0, -0.2721, -0.6474, 0.0);\n" +
            "const highp vec4 kYIQToB = vec4 (1.0, -1.1070, 1.7046, 0.0);\n" +
            "\n" +
            "void main() {\n" +
            "  mediump vec4 textureColor = texture2D(inputImageTexture, textureCoordinate);\n" +
            "  mediump vec4 textureColor2 = texture2D(inputImageTexture2, textureCoordinate2);\n" +
            "  highp float YPrime = dot (textureColor2, kRGBToYPrime);\n" +
            "  highp float I = dot (textureColor2, kRGBToI);\n" +
            "  highp float Q = dot (textureColor2, kRGBToQ);\n" +
            "  highp float hue = atan (Q, I);\n" +
            "  highp float chroma = sqrt (I * I + Q * Q);\n" +
            "  hue += (-hueAdjust);\n" +
            "  Q = chroma * sin (hue);\n" +
            "  I = chroma * cos (hue);\n" +
            "  highp vec4 yIQ = vec4 (YPrime, I, Q, 0.0);\n" +
            "  textureColor2.r = dot (yIQ, kYIQToR);\n" +
            "  textureColor2.g = dot (yIQ, kYIQToG);\n" +
            "  textureColor2.b = dot (yIQ, kYIQToB);\n" +
            "  mediump float percent = texturePercent * 0.01;\n" +
            "  mediump vec3 whiteColor = vec3(1.0);\n" +
            "  if (textureColor2.r <= 0.001 && textureColor2.g <= 0.001 && textureColor2.b <= 0.001) {\n" +
            "    textureColor2 = textureColor;\n" +
            "  } else {\n" +
            "    textureColor2.rgb = whiteColor - ((whiteColor - textureColor2.rgb) * (whiteColor - textureColor.rgb));\n" +
            "  }\n" +
            "  if (textureColor2.a > 0.00001) {\n" +
            "    textureColor2.a = textureColor2.a * percent;\n" +
            "  }\n" +
            "  gl_FragColor = textureColor2;\n" +
            "}";


    private int mTexturePercentLocation, mHueAdjustLocation;
    private float mTexturePercent, mHueAdjust;

    public GPUImageTextureFilter() {
        this(100.f, 0.0f);
    }

    public GPUImageTextureFilter(final float texturePercent, float hueAdjust) {
        super(LOOKUP_FRAGMENT_SHADER);
        mTexturePercent = texturePercent;
        mHueAdjust = hueAdjust;
    }

    @Override
    public void onInit() {
        super.onInit();
        mTexturePercentLocation = GLES20.glGetUniformLocation(getProgram(), "texturePercent");
        mHueAdjustLocation = GLES20.glGetUniformLocation(getProgram(), "hueAdjust");
    }

    @Override
    public void onInitialized() {
        super.onInitialized();
        setFloat(mTexturePercentLocation, mTexturePercent);
        setFloat(mHueAdjustLocation, mHueAdjust);
    }

    @Override
    public boolean isSupportIntensity() {
        return false;
    }

    @Override
    public float getIntensity() {
        return 0;
    }
}
